#pragma once
#include "Math.h"

class Transform
{
public:

	Transform();
	Transform(const glm::mat4& matrix);
	Transform(const glm::vec3& position);
	~Transform();

	void SetWorldMatrix(const glm::mat4& mat);

	void SetLocalTransform(const glm::mat4& localMat);

	void SetLocalPosition(const glm::vec3& localPos);
	void SetLocalScale(const glm::vec3& localScale);
	void SetLocalOrientation(const glm::quat& quat);

	const glm::mat4& GetWorldMatrix();
	const glm::mat4& GetLocalMatrix();

	const glm::vec3 GetWorldPosition() const;
	const glm::quat GetWorldOrientation() const;

	const glm::vec3& GetLocalPosition() const;
	const glm::vec3& GetLocalScale() const;
	const glm::quat& GetLocalOrientation() const;

	//Updates Local Matrix from R,T and S vectors
	void UpdateMatrices();

	bool HasUpdated() const { return mHasUpdated; }
	void SetHasUpdated(bool set) { mHasUpdated = set; }

	//Sets R,T and S vectors from Local Matrix
	void ApplyTransform();

	glm::vec3 GetUpDirection() const
	{
		glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f);
		up = GetWorldOrientation() * up;
		return up;
	}

	glm::vec3 GetRightDirection() const
	{
		glm::vec3 right = glm::vec3(1.0f, 0.0f, 0.0f);
		right = GetWorldOrientation() * right;
		return right;
	}

	glm::vec3 GetForwardDirection() const
	{
		glm::vec3 forward = glm::vec3(0.0f, 0.0f, 1.0f);
		forward = GetWorldOrientation() * forward;
		return forward;
	}

	const glm::mat4& GetParentMatrix() const { return mParentMatrix; }

protected:
	glm::mat4 mLocalMatrix;
	glm::mat4 mParentMatrix;
	glm::mat4 mWorldMatrix;

	glm::vec3 mLocalPosition;
	glm::vec3 mLocalScale;
	glm::quat mLocalOrientation;

	bool mHasUpdated = false;
	bool mDirty = false;
};
